package pl.agh.pp.zephyr.integration;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import pl.agh.pp.zephyr.logic.Engine;
import pl.agh.pp.zephyr.web.FacesFactory;

/**
 * Implementacja oparta o mikser openmcu
 * */
public class OpenMcuController extends McuController {

	private String url;

	private String prefix, httpPort;
	
	public OpenMcuController(Engine engine) {
		super(engine);
	}

	/**
	 * Wywoływać po ustawieniu hosta i portu
	 * */
	@Override
	public void init() {
		url = "http://" + getHost() + ":" + getHttpPort() + "/Status/";
	}

	public String getLoadDescription() {
		try {
			log.info("trying to reach mcu at: " + url);
			return getLoadHtmlFragment(getHttpContent(url));
		} catch (Exception e) {
			e.printStackTrace();
			FacesFactory
					.addErrorMessage("Failed to retrieve load information: "
							+ e.getMessage());
			return null;
		}
	}

	@Override
	/**
	 * Metoda realizuje POST'a HTTP.
	 * */
	public boolean connectRooms(String homeAlias, String alias, String ip,
			String port) throws Exception {
		String data = URLEncoder.encode("room", "UTF-8") + "="
				+ URLEncoder.encode(homeAlias, "UTF-8");
		data += "&" + URLEncoder.encode("address", "UTF-8") + "="
				+ URLEncoder.encode(alias + "#" + ip + "#" + port, "UTF-8");
		data += "&" + URLEncoder.encode("submit", "UTF-8") + "="
				+ URLEncoder.encode("Invite", "UTF-8");

		final URL yahoo = new URL("http://" + getHost() + ":" + getHttpPort()
				+ "/Invite/");
		URLConnection yc = yahoo.openConnection();
		BufferedReader in = null;
		StringBuilder sb = new StringBuilder();
		yc.setDoOutput(true);
		OutputStreamWriter wr = new OutputStreamWriter(yc.getOutputStream());
		wr.write(data);
		wr.flush();
		try {
			in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				sb.append(inputLine);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		return sb.toString().contains("Invite succeeded");
	}

	/**
	 * ultra zdupy metoda, która "wyciąga" tabelke z zajętością pokoji z htmla,
	 * pobranego z openmcu
	 * */
	private static final String getLoadHtmlFragment(final String html) {
		final String s = "<P><center>";
		final int start = html.indexOf(s), end = html.lastIndexOf("<P>");
		return (start == -1 || end == -1) ? "" : html.substring(
				start + s.length(), end);
	}

	private static final String getHttpContent(final String url)
			throws Exception {
		final URL yahoo = new URL(url);
		URLConnection yc = yahoo.openConnection();
		BufferedReader in = null;
		StringBuilder sb = new StringBuilder();
		try {
			in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				sb.append(inputLine);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {
					; // celowe olanie
				}
			}
		}
		return sb.toString();
	}

	@Override
	public boolean isActive() {
		try {
			if (active) {
				new URL(url).openConnection();
				return true;
			}
			return false;
		} catch (MalformedURLException e) {
			return false;
		} catch (IOException e) {
			return false;
		}
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	public String getHttpPort() {
		return httpPort;
	}

	public void setHttpPort(String httpPort) {
		this.httpPort = httpPort;
	}

}
